/**
 * $Id: WeixinService.java Jun 3, 2015 5:27:18 PM hdp
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.aurora.app.service;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Formatter;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.aurora.app.dao.WeixinAppTokenDao;
import com.aurora.app.entity.WeixinAppToken;
import com.aurora.base.dao.BaseDao;
import com.aurora.base.service.BaseService;
import com.aurora.base.util.HTTPSRequest;


/**
 * 主要用来处理微信事务
 * @author yongjiang.lin
 *
 */
@Service
public class WeixinService extends BaseService<WeixinAppToken> {
	private final Logger LOG = LoggerFactory.getLogger(this.getClass());

	private final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	private final static String get_jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

	@Resource
	private WeixinAppTokenDao weixinApptokenDao;
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tentcoo.base.service.impl.AbstractBaseServiceImpl#getBaseDao()
	 */
	@Override
	public BaseDao<WeixinAppToken> getBaseDao() {
		return this.weixinApptokenDao;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	private static String create_nonce_str() {
		return UUID.randomUUID().toString();
	}

	@Transactional
	public void getSign(HttpServletRequest request, String accountId) {
		String nonce_str = create_nonce_str();
		long timestamp = new Date().getTime();
		String string1;
		String signature = "";
		WeixinAppToken apptoken = this.getAccessToken(accountId);
		String jsapi = apptoken.getJsapiTicket();

		if (StringUtils.isBlank(jsapi)
				|| (timestamp - apptoken.getJsapiTime().getTime()) > 7200 * 1000L) {
			String requestUrl = get_jsapi_ticket_url.replaceAll("ACCESS_TOKEN",
					apptoken.getAccessToken());
			String result = null;
			try {
				result = HTTPSRequest.httpsRequest(requestUrl, "GET", null);
			} catch (Exception e) {
			}
			JSONObject json = JSONObject.parseObject(result);
			if (json.containsKey("ticket")) {
				jsapi = json.getString("ticket");
				apptoken.setJsapiTicket(jsapi);
				apptoken.setJsapiTime(new Date());
				this.weixinApptokenDao.merge(apptoken);
			}
		}
		String url = this.getUrl(request);

		// 注意这里参数名必须全部小写，且必须有序
		string1 = "jsapi_ticket=" + jsapi + "&noncestr=" + nonce_str
				+ "&timestamp=" + timestamp + "&url=" + url;
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		request.setAttribute("signature", signature);
		request.setAttribute("appId", apptoken.getAppId());
		request.setAttribute("nonceStr", nonce_str);
		request.setAttribute("timestamp", timestamp);

	}

	@Transactional
	public WeixinAppToken getAccessToken(String accountId) {
		// WeixinApptoken apptoken = this.weixinApptokenDao
		// .find("402881e8461795c201461795c2e90000");
		WeixinAppToken apptoken = null;
		if (StringUtils.isNotBlank(accountId)) {
			apptoken = this.weixinApptokenDao.find(accountId);
			if (apptoken == null) {
				apptoken = this.weixinApptokenDao.list(null).get(0);
			}
		} else {
			apptoken = this.weixinApptokenDao.list(null).get(0);
		}
		String accessToken = apptoken.getAccessToken();
		if (StringUtils.isNotEmpty(accessToken) && apptoken.getTime() != null) {
			String time = apptoken.getTime().getTime() + "";
			Date data = new Date();
			if ((data.getTime() - Long.parseLong(time)) < 7200 * 1000L) {
				return apptoken;
			}

		}
		
		//获取access_token
		String url = access_token_url.replaceAll("APPID", apptoken.getAppId())
				.replaceAll("APPSECRET", apptoken.getAppSecret());
		String result = null;
		try {
			result = HTTPSRequest.httpsRequest(url, "GET", null);
		} catch (Exception e) {
		}
		// System.out.println("gettoken result="+result);
		JSONObject json = JSONObject.parseObject(result);
		if (json.containsKey("access_token")) {
			accessToken = json.getString("access_token");
			apptoken.setAccessToken(accessToken);
			apptoken.setTime(new Date());
			this.weixinApptokenDao.merge(apptoken);
		}
		return apptoken;
	}

	private String getUrl(HttpServletRequest request) {
		String url = request.getScheme() + "://"; // 请求协议 http 或
		// https
		url += request.getHeader("host"); // 请求服务器
		url += request.getRequestURI(); // 工程名
		if (request.getQueryString() != null) {// 判断请求参数是否为空
			url += "?" + request.getQueryString(); // 参数

		}
		return url;

	}

}
